<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div class="card">
        <p id="firstName"></p>
        <p id="lastName"></p>
        <p id="age"></p>
    </div>
    <script>
        // 观察对象的所有属性
        function observe(obj) {
            for (let key in obj) {
                let internalValue = obj[key];
                let funcs = [];
                Object.defineProperty(obj, key, {
                    get: function () {
                        // 依赖收集
                        if (window.__func && !funcs.includes(window.__func)) {
                            funcs.push(window.__func)
                        }
                        return internalValue
                    },
                    set: function (val) {
                        // 派发更新
                        internalValue = val
                        for (let i = 0; i < funcs.length; i++) {
                            funcs[i]()
                        }
                    }
                })
            }
        }

        const user = {
            name: '张三',
            birth: '1991-1-1'
        }

        observe(user)

        function showFirstName() {
            document.querySelector('#firstName').textContent = '姓：' + user.name[0]
        }

        function showLastName() {
            document.querySelector('#lastName').textContent = '名：' + user.name.slice(1)
        }

        function showAge() {
            let birthData = new Date(user.birth);
            let today = new Date();
            today.setHours(0);
            today.setMinutes(0);
            today.setMilliseconds(0);
            let thisYearBirth = new Date(today.getTime() - birthData.getTime());
            let age = Math.abs(thisYearBirth.getUTCFullYear() - 1970)
            document.querySelector('#age').textContent = '年龄：' + age;
        }

        window.__func = showFirstName;
        showFirstName()
        window.__func = null;

        window.__func = showLastName;
        showLastName()
        window.__func = null;

        window.__func = showAge;
        showAge();
        window.__func = null;

        // 1、修改name,希望自动调用依赖该属性的函数
        user.name = '李四'
        // 2、修改birth,希望自动调用依赖该属性的函数
        user.birth = '1988-7-7';

    </script>
</body>

</html>